#ifndef __RANDOM_GEN_H__
#define __RANDOM_GEN_H__
#include <random>
#include <type_traits>

template <class T, class Enable = void>
class Random {};

template <class T>
class Random<T, typename std::enable_if_t<std::is_floating_point_v<T>>> {
public:
    explicit Random(T a, T b = 1.0)
        : mDistribution(a, b) {
        std::mt19937 mGen(mRandomDevice());
    }

    T operator () () {
        return mDistribution(mGen);
    }
private:
    std::random_device mRandomDevice;
    std::mt19937 mGen;
    std::uniform_real_distribution<T> mDistribution;
};

template <class T>
class Random<T, typename std::enable_if_t<std::is_integral_v<T>>> {
public:
    Random(T a, T b = std::numeric_limits<T>::max())
        : mDistribution(a, b) {
        std::mt19937 mGen(mRandomDevice());
    }

    T operator () () {
        return mDistribution(mGen);
    }
private:
    std::random_device mRandomDevice;
    std::mt19937 mGen;
    std::uniform_int_distribution<T> mDistribution;
};

#endif